/******************************************************************************* 

*******************************************************************************/

#include "delay.h"
#include "sys.h"
#include "oled.h"
#include "bmp.h"
#include "DHT11.h"
#include "timer.h"
#include "led.h"
#include "usart.h"
 #include "adc.h"
 
#include "key.h"
#include "beep.h"
#include <math.h>
 
u8 temp, humi, last_temp, last_humi; 
int Max_air=20;
int air;
u8 Max_temp=31,Max_humi=80;
u8 CurrItem=1;
u16 alarm_is_free = 10000;//报警器是否被手动操作，如被操作即设置为0
extern u16 bleflag;
typedef enum{
	HARD_OK =0,
	DHT11_ERR,
	MQ_135_ERR,
	MAX_3010X_ERR,
}Hardware_Err_Typedef;

void OLED_Dis_Menu(void);
void OLED_Dis_DHT(u8 temp, u8 hum, int air);
void OLED_Dis_Blox(int heart, int oxygen);
void OLED_Dis_Err(Hardware_Err_Typedef err);

void DealKeyVal(u16 KeyVal);
u8 Menu_DealKeyVal(u16 KeyVal);
u8 SysStandby_DealKeyVal(u16 KeyVal);

void SettingMenu(void);

//初始化，检查温湿度及空气传感器是否异常，并将异常信息显示到oled上
void DEV_Init(void)
{
		DHT11_Init();
		if(DHT11_Check() == 1)
		{
			OLED_Dis_Err(DHT11_ERR);
			delay_ms(400);
		}
		Adc_Init();
		if(Get_Adc_Average(ADC_Channel_4,5)>2500)
		{
				OLED_Dis_Err(MQ_135_ERR);
				delay_ms(400);
		}
		
//		OLED_Dis_Err(MAX_3010X_ERR);
//		delay_ms(400);
}

u16 key;
 int main(void)
 {	
	  
		int adc,cnt=0;
		float volt;
		delay_init();	    	 
		NVIC_Configuration(); 	 
		BEEP_Init();
		OLED_Init();			
		OLED_Clear();
		DEBUG_UART_Config();
		KEY_Init();
		LED_Init();
		TIM3_Int_Init(500-1,720-1);
        DEV_Init();
		OLED_Clear(); 
		OLED_Dis_Menu();
	while(1)		
	{		
		if(cnt++ ==1000)
		{
			cnt = 0;
			adc =	Get_Adc_Average(ADC_Channel_4,5);
			volt = adc*3.3/4096;
//	        air = pow((3.4880*10*volt)/(5-volt),(1.0/0.3203));
            air = ((int)((float)volt*33000)/4095);
			//获取温湿度
			DHT11_Read_Data( &temp, &humi);
//            printf("1223");
            //检测温湿度不为零，显示在oled上
			if(last_temp!=temp || last_humi!=humi)
			{
				OLED_Dis_DHT(temp,humi,air);
                printf("%d%d%d%d%d%d",temp,humi,air,Max_temp,Max_humi,Max_air);
               
			}
		}
        key = bleflag;//按键值由蓝牙标志位获得，发送规定字符，返回对应标志位
        if(!bleflag)//如有蓝牙标志位返回，不进行按键扫描
		key = Key_GetValue();         //按键扫描
        
		if(key)
		DealKeyVal(key);
//		if(!KEY1_IO())
//		{
//				printf("%d\r\n",GetTime());
//		}
        if( alarm_is_free == 10000)//alarm_is_free = 10执行执行自动控制，初始值10，按下按键后alarm_is_free = 0
            if(temp>Max_temp || humi>Max_humi || air>Max_air)
            {
                if(cnt<500)BEEP=1;
                else if(cnt<1000)BEEP=0;
            }else BEEP=0;
		if( alarm_is_free < 10000 )
        {
            alarm_is_free++ ;
            BEEP=0;
            delay_ms(1);
        }
		
		delay_ms(1);
	}	  
	
}


void Standby(void)//待机，可长按进入低功耗模式·
{
	u16 key,flag;
		OLED_Clear();
	while(1)
	{
		BEEP=0;
		key = Key_GetValue();          //按键扫描
		flag = SysStandby_DealKeyVal(key);
		if(flag == 1)break;
	}
		OLED_Dis_Menu();	
}

//显示主界面固定内容
void OLED_Dis_Menu(void)
{
		OLED_ShowCHinese(23,0,0);//温
		OLED_ShowCHinese(41,0,1);//湿
		OLED_ShowCHinese(59,0,2);//度
		OLED_ShowCHinese(77,0,43);//计
		
		OLED_ShowCHinese(0,2,0);//温
		OLED_ShowCHinese(18,2,2);//度
		OLED_ShowChar(38,2,':',16);//: 
		OLED_ShowCHinese(100,2,32);//℃
		
		OLED_ShowCHinese(0,4,1);//湿
		OLED_ShowCHinese(18,4,2);//度
		OLED_ShowChar(38,4,':',16);//:
		OLED_ShowCHinese(100,4,33);//％
		
		
		OLED_ShowCHinese(0,6,3);//空
		OLED_ShowCHinese(18,6,4);//气
		OLED_ShowChar(38,6,':',16);//: 
}
void OLED_Dis_DHT(u8 temp, u8 hum, int air)
{
	OLED_ShowNum(60,2,temp,3,16);
	OLED_ShowNum(60,4,hum,3,16);
	OLED_ShowNum(60,6,air,3,16);
}
void OLED_Dis_Blox(int heart, int oxygen)
{
}
void OLED_Dis_Err(Hardware_Err_Typedef err)
{
	OLED_ShowCHinese(36,0,35);//硬
	OLED_ShowCHinese(54,0,36);//件
	OLED_ShowCHinese(72,0,37);//检
	OLED_ShowCHinese(90,0,38);//测
	switch(err)
	{
	case HARD_OK      :
		break;
	case DHT11_ERR    :
		OLED_ShowCHinese(0,2,0);//温
		OLED_ShowCHinese(18,2,1);//湿
		OLED_ShowCHinese(36,2,2);//度
		OLED_ShowCHinese(54,2,26);//传
		OLED_ShowCHinese(72,2,27);//感
		OLED_ShowCHinese(90,2,28);//器
		OLED_ShowCHinese(108,2,30);//异
	  OLED_ShowCHinese(108,2,31);//常
		break;
	case MQ_135_ERR   :
		OLED_ShowCHinese(0,2,3);//空
		OLED_ShowCHinese(18,2,4);//气
		OLED_ShowCHinese(36,2,2);//度
		OLED_ShowCHinese(54,2,26);//传
		OLED_ShowCHinese(72,2,27);//感
		OLED_ShowCHinese(90,2,28);//器
		OLED_ShowCHinese(108,2,30);//异
	  OLED_ShowCHinese(108,2,31);//常
		break;
	case MAX_3010X_ERR:
		OLED_ShowCHinese(0,2,9);//心
		OLED_ShowCHinese(18,2,11);//血
		OLED_ShowCHinese(36,2,12);//氧
		OLED_ShowCHinese(54,2,26);//传
		OLED_ShowCHinese(72,2,27);//感
		OLED_ShowCHinese(90,2,28);//器
		OLED_ShowCHinese(108,2,30);//异
	  OLED_ShowCHinese(108,2,31);//常
		break;
	}
}



/****************************************
* 函数名称: DealKeyVal()
* 输入参数: KeyVal :键值
* 输出参数: 无
* 功    能: 键值处理函数
*
*****************************************/
void DealKeyVal(u16 KeyVal)
{
    //static  u16  LastKeyVal = 0;
//	u32  differ_time=0;   //时间差值
//	static  u32  long_pressed_time=0;   //计时长按按键不松开
//	static  u32  long_pressed_time_cnt=0;   //计时长按按键不松开
//传过来的值是事件与键值取或，再分别按位与将事件与键值提出来
    u16  KeyEvent  = KeyVal & KEYEVENTMASK; //按键事件
    u16  CurKeyVal = KeyVal & KEYIDMASK;    //当前键值

//    Uart2Print("\r\nCurKeyVal = 0X%02d\r\n",CurKeyVal);
    switch(KeyEvent)
        {

//        case KEY_EVENT_PRESSED:  // 按键按下
//        {
////            Uart2Print("\r\n按键按下 = 0X%04x\r\n",KeyVal);
//            switch(CurKeyVal)
//                {
//                case KEY_ID_1:
//                {

//                    break;
//                }

//                default:
//                    break;
//                }

//            break;
//        }

        case KEY_EVENT_SHORT:    // 单击健
        {
            printf("\r\n单击键 = 0X%04x\r\n",KeyVal);
            switch(CurKeyVal)
                {
                case KEY_ID_1: //编码器按键
                {
										SettingMenu();//进入设置
                    break;
                }
                default:
                    break;
                }

            break;
        }

        case KEY_EVENT_LONG_PRESSED:  //长按键未释放
        {
            
            switch(CurKeyVal)
                {
                case KEY_ID_1:
                {
										Standby();//进入待机

                    break;
                }

                default:
                    break;
                }

            break;
        }

        case KEY_EVENT_LONG_RELEASE:  //长按键释放
        {
//            Uart2Print("\r\n长按键释放 = 0X%04x\r\n",KeyVal);
//            switch(CurKeyVal)
//                {
//                case KEY_ID_1:
//                {
//                    //Standby();//进入待机
//					//long_pressed_time_cnt = 0;
//                    break;
//                }

//                default:
//                    break;
//                }

            break;
        }

        case KEY_EVENT_DOUBLE_SHORT:  //双击键
        {
            printf("\r\n双击键 = 0X%04x\r\n",KeyVal);
            switch(CurKeyVal)
                {
                case KEY_ID_1: //编码器按键
                {
                    break;
                }

                default:
                    break;
                }

            break;
        }



        default:
            break;
        }

//    LastKeyVal = KeyVal;
}


/****************************************
* 函数名称: StandbyDealKeyVal() 待机下按键处理函数
* 输入参数: KeyVal :键值
* 输出参数: 无
* 功    能: 键值处理函数
*
*****************************************/
u8 SysStandby_DealKeyVal(u16 KeyVal)
{
    u8   flag = 0;
    u16  KeyEvent  = KeyVal & KEYEVENTMASK; //按键事件
    u16  CurKeyVal = KeyVal & KEYIDMASK;    //当前键值
    
    switch(KeyEvent)
        {
        case KEY_EVENT_SHORT:    // 单击健
        {
            switch(CurKeyVal)
                {
                case KEY_ID_1:  //编码器按键
                {
                    flag = 1;//阈值加1
                    bleflag = 0;
                    break;
                }
                default:
                    break;
                }

        }
        break;
				case KEY_EVENT_LONG_PRESSED:  //长按键未释放
        {
            
            switch(CurKeyVal)
                {
                case KEY_ID_1:
                {
					flag = 2;
                    bleflag = 0;

                    break;
                }

                default:
                    break;
                }

            break;
        }


        case KEY_EVENT_DOUBLE_SHORT:  //双击键
        {
            printf("\r\n双击键 = 0X%04x\r\n",KeyVal);
            switch(CurKeyVal)
                {
                case KEY_ID_1: 
                {
					flag = 3;
                    bleflag = 0;
                    break;
                }

                default:
                    break;
                }

            break;
        }
				case KEY_EVENT_SHORT_LONG_PRESSED :
						printf("\r\n短长按KEY_EVENT_SHORT_LONG_PRESSED = 0X%04x\r\n",KeyVal);
				flag = 4;
                bleflag = 0;
						break;

        default:
            break;
        

        }

    return flag;
}



/****************************************
* 函数名称: StandbyDealKeyVal() 待机下按键处理函数
* 输入参数: KeyVal :键值
* 输出参数: 无
* 功    能: 键值处理函数
*
*****************************************/
u8 Menu_DealKeyVal(u16 KeyVal)
{
    u8   flag = 0;
    u16  KeyEvent  = KeyVal & KEYEVENTMASK; //按键事件
    u16  CurKeyVal = KeyVal & KEYIDMASK;    //当前键值

    switch(KeyEvent)
        {
        case KEY_EVENT_SHORT:    // 单击健
        {
            switch(CurKeyVal)
                {
                case KEY_ID_1:  //编码器按键
                    
                    flag = 1;   //刷新显示
                    break;

//                case KEY_ID_2: //电源按键  更改项目取值
//                {
//                    //SysParameterSetDeal(SEQUENCE_ORDER);
//                    flag = 1;   //刷新显示
//                    break;
//                }
                default:
                    break;
                }
        }
		break;
		case KEY_EVENT_LONG_PRESSED:    //长按未释放
        {
					if(CurKeyVal == KEY_ID_1)
					{
						//保存退出 显示88 2秒
						
						flag = 2;//退出菜单
					}
		}
        break;
        }

    return flag;
}


/****************************************
* 函数名称: SettingMenu() 
* 输入参数: 
* 输出参数: 无
* 功    能: 
*
*****************************************/
void SettingMenu(void)
{
//    extern u16 bleflag;
	u16 key,flag,time=0;
	u8 dis_flag,last_disflag;
	OLED_Clear();
	OLED_ShowCHinese(25,0,39);//报
	OLED_ShowCHinese(43,0,40);//警
	OLED_ShowCHinese(61,0,41);//设
	OLED_ShowCHinese(79,0,42);//置
	BEEP=0;
    
	while(1)
	{
		time++;
        
		key = bleflag;//按键值由蓝牙标志位获得，发送规定字符，返回对应标志位
       
        if(!bleflag)//如有蓝牙标志位返回，不进行按键扫描
		key = Key_GetValue();  
        //按键扫描
		flag = SysStandby_DealKeyVal(key);//对返回的按键值进行处理
		if(flag == 1)//单击 ，对阈值进行上调
		{
			switch(CurrItem)
			{
				case 1:Max_temp++; if(Max_temp==50)Max_temp=0;break;
				case 2:Max_humi++; if(Max_humi==101)Max_temp=0;break;
				case 3:Max_air++; if(Max_air==150)Max_temp=0;break;
			}
			 
		}
		if(flag == 4)//短按一下＋长按 ，对阈值进行下调
		{
			switch(CurrItem)
			{
				case 1:Max_temp--; if(Max_temp==0)Max_temp=50;break;
				case 2:Max_humi--; if(Max_humi==0)Max_temp=101;break;
				case 3:Max_air--; if(Max_air==0)Max_temp=150;break;
			}
			 
		}
		if(flag == 2)break;//长按 保存退出
		if(flag == 3)//双击 切换条目
		{
			CurrItem++;
			if(CurrItem == 4) CurrItem = 1;
		}
		
		//下面实现菜单条目闪烁
		last_disflag = dis_flag;
		if(time<25000)
			dis_flag = 0;
        else if(time<50000)
			dis_flag = 1;
//        else time=0;    

            if(last_disflag != dis_flag)
                if(dis_flag == 0)	
                {
                    OLED_ShowCHinese(0,2,0);//温
                    OLED_ShowCHinese(18,2,2);//度
                    OLED_ShowChar(38,2,':',16);//: 
                    OLED_ShowCHinese(100,2,32);//℃
                
                    OLED_ShowCHinese(0,4,1);//湿
                    OLED_ShowCHinese(18,4,2);//度
                    OLED_ShowChar(38,4,':',16);//:
                    OLED_ShowCHinese(100,4,33);//％
                
                    
                    OLED_ShowCHinese(0,6,3);//空
                    OLED_ShowCHinese(18,6,4);//气
                    OLED_ShowChar(38,6,':',16);//: 
                    
                    
                    OLED_ShowNum(60,2,Max_temp,3,16);
                    OLED_ShowNum(60,4,Max_humi,3,16);
                    OLED_ShowNum(60,6,Max_air,3,16);
                }
                else if(dis_flag ==1)
                {
                    switch(CurrItem)
                    {
                        case 1:
                            OLED_ShowString(0,2, "                ",16);
                            break;
                        case 2:
                            OLED_ShowString(0,4, "                ",16);
                            break;
                        case 3:
                            OLED_ShowString(0,6, "                ",16);
                            break;
                    }
                 }
         
//        else time=0;
        
	}
	
		OLED_Clear();
		OLED_Dis_Menu();	
	delay_ms(1000);
}
